import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Company } from "src/modules/company/company.entity";
import { CompanyService } from "src/modules/company/company.service";
import { User } from "src/modules/user/user.entity";
import { UserService } from "src/modules/user/user.service";
import { dateNewFirst } from "src/utils/util";
import { Repository } from "typeorm";
import { Log } from "./log.entity";

@Injectable()
export class LogService {
  constructor(
    @InjectRepository(Log)
    private readonly logRepository: Repository<Log>,
    private readonly usersService: UserService,
    private readonly companyService: CompanyService
  ) {}

  find(log: string | Log): Promise<Log> {
    const id = log instanceof Log ? log.id : log;
    return this.logRepository.findOneOrFail({
      where: { id },
      relations: ["user"],
    });
  }

  findWithCompany(id: string): Promise<Log> {
    return this.logRepository.findOneOrFail({
      where: { id },
      relations: ["company", "user"],
    });
  }

  async findAll(): Promise<[Log[], number]> {
    const ans = await this.logRepository.findAndCount({
      relations: ["user"],
    });
    const logs = ans[0].sort(dateNewFirst);
    return [logs, ans[1]];
  }

  async findByUser(user: User | string) {
    const target =
      user instanceof User ? user : await this.usersService.find(user);
    const ans = await this.logRepository.findAndCount({
      where: { user: target },
    });
    const logs = ans[0].sort(dateNewFirst);
    return [logs, ans[1]];
  }

  async findByCompany(company: Company | string) {
    const target =
      company instanceof Company
        ? company
        : await this.usersService.find(company);
    const ans = await this.logRepository.findAndCount({
      where: { company: target },
      relations: ["user"],
    });
    const logs = ans[0].sort(dateNewFirst);
    return [logs, ans[1]];
  }

  async create(createLogDto: {
    targetId: string;
    method: "PUT" | "DELETE" | "POST";
    company: Company;
    user: User;
    type:
      | "Bank"
      | "Client"
      | "Company"
      | "Delivery"
      | "Order"
      | "Quality"
      | "Type"
      | "User";
  }): Promise<Log> {
    const log = new Log();
    Object.assign(log, {
      ...createLogDto,
    });
    const ans = await this.logRepository.save(log);
    return ans;
  }
}
